[レポート] ANT401 : Amazon Redshift ディープダイブ & ベストプラクティス #reinvent
本記事はAWS re:Invent 2018のセッション「ANT401 : Deep Dive and Best Practices for Amazon Redshift」のレポートです。
既存のAmazon Redshiftユーザー向けに、各リージョンに展開中・プレビュー中の機能も含めた2018年11月30日時点のAmazon Redshiftの機能が EXPERT (400) レベルで網羅されています。
セッションについて
セッションURL
https://www.portal.reinvent.awsevents.com/connect/sessionDetail.ww?SESSION_ID=90059
スピーカー
- Tony Gibbs - Data Warehousing Solutions Architect
概要
In this session, we take an in-depth look at how modern data warehousing blends and analyzes all your data, inside and outside your data warehouse, without moving the data. This helps you gain deeper insights in running your business. We also cover best practices on how to design optimal schemas, load data efficiently, and optimize your queries to deliver high throughput and performance.
資料
本記事の画像はすべて YouTube 動画をキャプチャーしたものです。
アーキテクチャーコンセプト
Amazon Redshift について
- Amazon Redshift は PostgreSQL のフォーク
- ストレージを列指向に書き換え
- MPP(massively parallel)
- 128ノード
- 2PB
- までスケールするようになった
- Analytics に必要な関数群を追加
- AWS連携
- S3(load/unload)
- KMS(encryption)
- IAM(authentication)
リリース
- 2013/02/14のバレンタインデーにリリース
- 隔週で機能追加
Amazon Redshift アーキテクチャー
- SQL の実行について
- JDBC/ODBC ドライバーを提供
- PostgreSQL の各種ドライバーとも互換性あり
- リーダーノード
- クエリーの coordinator
- PostgreSQL の pg_catalog 相当のスキーマメタデータも管理
- コンピュートノードの役割
- データが保存されている
- 2〜128 のコンピュートノードがリーダーノード配下で動作
- クエリーはコンピュートノードで並列に実行
- MPP
- shred nothing
- S3 連携
- S3 経由のデータのロード・アンロードが可能
- バックアップは非同期に実行され、S3 保存される
- リストアは S3 のバックアップから実行される
- Amazon Redshift Spectrum
- Redshift から S3 オブジェクトにクエリーできる
- S3/Redshift 間で JOIN できる
Terminology and Concepts:Columnar
- DWH で利用するような SQL ではスキーマの一部のカラムにしか問い合わせないことが多い
- 列指向データベースの場合、このような特定カラムへ効率よくアクセスできる
Terminology and Concepts:圧縮
- 圧縮のメリット
- 容量あたり、より多くのデータを保存できる→ディスク容量の削減に貢献
- 3倍〜4倍の圧縮率
- I/O が減る→パフォーマンスに貢献
- 列指向なので、圧縮対象のデータ型は同じ。カラムの型にあった圧縮を選択可能
- 容量あたり、より多くのデータを保存できる→ディスク容量の削減に貢献
analyze compression
コマンドを実行すれば、データに適切な圧縮形式を教えてくれる
ベストプラクティス:圧縮
- 全テーブルで圧縮する
ANALYZE COMPRESSION
コマンドでおすすめ圧縮フォーマットがわかる- RAW(圧縮不要)となるケース
- データ量が少ない
- NULL の占める量が多いスパースなカラム
- RAW(圧縮不要)となるケース
Terminology and Concepts:ブロック
- データは 1MB のイミュータブルなブロックに保存される
- ブロック単位でエンコードされる
- ブロックサイズが大きいので、1ブロックに100万を超えるデータが格納されることもある
Terminology and Concepts:ゾーンマップ
- インメモリーデータ構造
- 各ブロックの最大・最小値を管理
- ブロックアクセス時に、そのブロックの最大・最小値をチェックすれば、スキャンが必要かわかる
Terminology and Concepts:データのソート
- データがソートされたあとで(複数の)ブロックに格納
- ゾーンマップのオーバーラップがなくなる
- スキャンすべきブロックも限定される
CREATE TABLE
時にSORTKEY
でソートするカラムを指定
CREATE TABLE deep_dive ( aid Invent -- audiance_id ,loc CHAR(3) -- location ,dt DATE -- date ) SORTKEY (dt, loc);
ベストプラクティス:ソートキー
- 効果高い
- フィルターでよく利用するカラム(タイムスタンプ系カラムなど)
- 効果低い
- データが少ないテーブル
Terminology and Concepts:カラムのマテリアライズ
- ゾーンマップを活かすのが狙い
- ディメンションテーブルとファクトテーブルでJOINし、ディメンションテーブルのカラムでフィルターするケースがある
- 大量の I/O が発生
- ファクトテーブルをフルスキャンしてハッシュジョインするケースも
- ディメンションテーブルにあるフィルター用カラムをファクトテーブルに用意
- ゾーンマップとの相乗効果で I/O を大幅に減らせる
- 大量の I/O が発生
- where 句の predicate に関数を利用
- ゾーンマップを使えない
- 計算済みカラムを用意すれば、ゾーンマップと連携できる
Terminology and Concepts:スライス
- スライスは仮想コンピュートノードのようなもの
- データパーティション、コンピュートの単位
- 1ノードあたりのスライスの数
- xlarge → 2
- 8xlarge → 16
- 各スライスはスライス内のデータだけを処理する
- データをどのように分散するかが重要
データ分散
- KEY:キーとなるカラムのハッシュ値で決まる。
- 大きいテーブル同士のJOINに利用するカラムに利用
- SLICE 内に閉じて(co-locate) JOIN できる
- スライス間のレコード数のばらつき(skew)が発生しないようにすること
- 大きいテーブル同士のJOINに利用するカラムに利用
- ALL : 各スライスに配置
- 小さいディメンションテーブルに向いている
- EVEN : ラウンドロビン
- 無難
- AUTO : 最近リリース。現在のデフォルト
- データが小さいうちは ALL。増えると EVEN
ベストプラクティス:テーブルデザインまとめ
- 全テーブルを圧縮する
- フィルターに利用されるカラムにソートキーを利用
- ディメンションテーブルにあるフィルター用カラムはファクトテーブルにマテリアライズする
- カラム長さは適切に設定。(Oracle 系の人は
VARCHAR 255
が大好き)
Data storage, ingestion, and ELT
Terminology and Concepts:冗長性(Redundancy)
- ストレージ容量
- 冗長性のために、データは複数ノードにコピーされている
- ユーザーが見えるデータ容量はコピー分を含んでいないデータ容量
- 一時テーブル
- S3 にバックアップされない
- 別ノードにコピーされない
- 結果、書き込みば2倍速い
Terminology and Concepts:トランザクション
- トランザクション対応/ACID 準拠
- 分離レベル:serializable
- 2相コミット対応(ローカルノードレベル、ノード全体レベル)
- 2018年8月のパッチでコミットが非常に早くなった
- トランザクションを利用してコミットをへらすこと
- 各 DDL の裏では暗黙にトランザクションが利用されている
Terminology and Concepts:コピー文
- S3 からのデータロード
- 高速化のチップ
- スライスの倍数にファイル分割すると平行でデータが取り込まれる
- 各ファイルのサイズは gzip 圧縮後 1MB〜1GB にする
- 標準的なCSVフォーマットを利用
データ・インジェスション:Amazon Redshift Spectrum
- Spectrum は外部テーブルの一種
- データ・インジェスションに利用できる
- COPY 文とことなり、SQLが使えるので以下が可能
- 集約
- 列の指定
design consideration : データ・インジェスション
- Redshift は大量のデータ処理に特化している
- 少量のデータ更新と何万のデータ更新で処理時間が変わらないこともある
- DELETE/UPDATE
- DELETE
- 削除フラグを立てる
- UPDATE
- 削除フラグを立てる
- 新しいレコードを追記
- DELETE
データ・インジェスション:重複/UPSERT
S3 のデータをもとにUPSERT する場合の例
処理内容 | SQL |
---|---|
トランザクション開始 | BEGIN; |
一時テーブルを作成 | CREATE TEMP TABLE staging(LIKE deep_dive); |
一時テーブルに S3 からデータをロード | COPY STAGING FROM 's3://bucket/dd.csv':'cred' COMPUPDATE OFF; |
更新対象レコードを削除 | DELETE FROM deep_dive d USING staging s WHERE d.aid=s.aid; |
一時テーブルのデータをテーブルに INSERT | INSERT INTO deep_dive SELECT * FROM staging; |
一時テーブルを削除 | DROP TABLE staging; |
トランザクション終了 | COMMIT; |
ベストプラクティス:ETL
- ワークフローをトランザクションで明示的に囲む
- DELETE ではなく DROP/TRUNCATE TABLE を利用
- ステージングテーブル
- 一時テーブルを利用。永続テーブルの場合はバックアップを無効化する
- 自動圧縮は無効化する(
COMPUPDATE OFF
)
VACUUM と ANALYZE
- VACUUM
- 削除フラグのついたレコードの削除→自動でバックグラウンド実行されるようになった
- グローバルなテーブルのソート → マニュアル実行が必要
- ANALYZE
- 統計データの更新 → 自動実行される
Workload 管理とクエリーモニタリングルール
ワークロード管理(WLM)
- 異なるワークロードごとにキューの管理をしたい
- ダッシュボードユーザー
- データサイエンティスト
Terminology and Concepts : WLM 属性
- キュー
- ユーザー・セッション変数などによって適切なキューでSQLが実行させる
- Short Query Acceleration(SQA)
- 管理コンソールで ON/OFF を切り替える
- 数秒で処理が終わると見込まれる SQL を、専用のキュー(short query queue)で実行
- 既存のクエリーの実行のためにキューで待たされることなく、即時に実行できる
Terminology and Concepts : クエリー属性
- クエリースロット
- concurrency スケーリング
- キューがいっぱいの場合、セカンダリークラスターでキューが処理される
Terminology and Concepts : キュー属性
- concurrency scaling
- プレビュー
- キューがいっぱいのときに、裏で別のクラスター(secondary cluster)を起動し、そのクラスターで SQL が実行される
- 別クラスターの起動はクレジットベース
[速報]待望の新機能”Amazon Redshift concurrency scaling”が発表されました! #reinvent
ワークロード管理:例
Query monitoring rules(QMR)
- WLM の拡張
- 条件を満たすクエリーに対するアクション(killなど)を設定できる
- 巨大なテーブル同士の直積の SQL をアボートさせる
- 何百万ものレコードを返すの SQL(アンロードコマンドで対応すべき) をアボートされる
- 長時間実行されている・リソースを大量消費する SQL をログ出力
ベストプラクティス:WLM と QMR
- WLM のキューはできるだけ少なく(アイドルなキューが発生しないように3つまで)
- データインジェスション/ETL の並列度は 2〜3に留める
- 実行時間の長い SQL は QMR でロギングする
Terminology and connects:ノードタイプ
- DC2:SSD
- DS2:HDD
各ノードタイプは2種類のサイズがある
サイジング
- 非圧縮状態でのデータサイズを試算
- 圧縮率が 3倍と仮定(実際はもっと高い事が多い)
- 30%-40%の空きを用意(一時作業領域のため)
- パフォーマンス要件に応じて SSD(DC2) または HDD(DS2) を選択
リサイズ
- 2種類のリサイズ方式
- クラシックリサイズ
- 特徴
- 何時間もかかる
- 暗号の切り替えが可能
- ノードタイプの変更可能
- 手順
- 新規クラスターを起動
- データを旧から新に再配布
- クラスター起動完了後は、エンドポイントが新リーダーノードを指すようにする
- 特徴
- elastic リサイズ
- 特徴
- 分のオーダーでリサイズが終わる
- リサイズ中のクエリー
- 参照系SQL書き込みは再実行
- トランザクションを使った更新系SQLはロールバックされる
- 手順
- 各ノードのバックアップを取る
- 既存クラスターにノードを追加
- スライス単位でデータを再配布(シャッフル)
- 例えば、3 node x 16 スライス(=合計48スライス)の場合、4 node x 12 スライス(=合計48スライス)にする
- 特徴
elastic リサイズのノード増減パターン
8xlarge はスライス数が多いため、自由度が高い
リサイズ:elastic と classic のどちらを使う?
ベストプラクティス:クラスターサイジング
- 本番では冗長性のためにマルチノードクラスター(少なくとも2ノード)を利用
- 1 ノードクラスターは開発・テスト・QA向け
- 一時作業領域のために 20% の空き容量を常に確保
- DC1を使っているならDC2に移行
- 遥かに速い
- RI も引き継がれる
Additional Resources
AWS Labs on Github - Amazon Redshift
- 分析・デバッグに便利なスクリプト群